package cn.shengchao.examstar.me.course.ohs.local.appervices;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.shengchao.examstar.me.course.acl.ports.repositories.IContactUserCourseRepository;
import cn.shengchao.examstar.me.course.acl.ports.repositories.IMyCourseRepository;
import cn.shengchao.examstar.me.course.domain.ContactUserCourseKnowledge;
import cn.shengchao.examstar.me.course.domain.ContactUserLearning;
import cn.shengchao.examstar.product.acl.ports.repositories.IProductRepository;
import cn.shengchao.examstar.product.domain.entity.Course;
import cn.shengchao.examstar.product.domain.entity.CourseKnowledgeNode;
import cn.shengchao.examstar.me.course.domain.CourseStatisticVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @program: examstarapi
 * @description: 客服用户画像统计服务
 * @author: Xiong weiqiang
 * @create: 2025-04-19 15:56
 */
@Component
public class ContactUserCourseStatisticAppService {

    @Autowired
    private IMyCourseRepository myCourseRepository;
    @Autowired
    private IContactUserCourseRepository contactUserCourseRepository;
    @Autowired
    private IProductRepository productRepository;

    public List<ContactUserLearning> queryUserCourseLearning(String productName,String specifications, Long userId) {
        List<ContactUserLearning> list=new ArrayList<>();
        List<Long> myCourseIds = myCourseRepository.getMyCourseListByProductName(userId, productName);
//        List<Course> courses= productRepository.findCourseByProductNameAndSpecifications( productName, null);
        if (CollUtil.isNotEmpty(myCourseIds)) {
            List<Course> courses = productRepository.findCourseByIds(myCourseIds);
            if (CollUtil.isNotEmpty(courses)) {
                if (courses.size() > 5) {
                    courses = courses.subList(0, 5);
                }

//            courses=courses.subList(0,1);
                List<CompletableFuture<ContactUserLearning>> futures = new ArrayList<>();
                List<Long> courseIds = courses.stream().map(Course::getId).toList();
                courseIds.forEach(courseId -> {
                    futures.add(CompletableFuture.supplyAsync(() -> statisticUserCourseLearning(courseId, userId)));
                });
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
                list = futures.stream().map(CompletableFuture::join).toList();
                Map<Long, Course> courseMap = courses.stream().collect(Collectors.toMap(Course::getId, course -> course));
                list.forEach(contactUserLearning -> {
                    contactUserLearning.setCourseName(courseMap.get(contactUserLearning.getCourseId()).getName().getValue());
                    contactUserLearning.setClassHour(courseMap.get(contactUserLearning.getCourseId()).getClassHour());
                    contactUserLearning.setImgUrl(courseMap.get(contactUserLearning.getCourseId()).getImageUrl());
                });
            }
        }
        return list;
    }
    /**
     * 统计用户学习课程
     * @param userId
     * @return
     */
    public CourseStatisticVo statisticUserCourseLearning(Long userId) {
        List<Long> list = myCourseRepository.getMyCourseList(userId);
        CourseStatisticVo courseStatisticVo = new CourseStatisticVo();
        courseStatisticVo.setSysUserId(userId);
        int courseTotalNum = 0;
        double courseSecondTotal= 0D;
        long userLearningSecondTotal = 0L;
        int payKnowledgeNodeNum = 0;
        int freeUnlockKnowledgeNodeNum = 0;
        BigDecimal payKnowledgeNodePriceSum = BigDecimal.ZERO;
        BigDecimal freeUnlockKnowledgeNodePriceSum = BigDecimal.ZERO;
        Integer inLearningCourseNum = 0;
        Integer finishCourseNum = 0;
        List<ContactUserLearning> contactUserLearnings=new ArrayList<>();
        List<CompletableFuture<ContactUserLearning>> futures = new ArrayList<>();
        Long courseTimeTotal = 0L;

        if (CollUtil.isNotEmpty(list)) {
            Map<Long, ContactUserLearning> contactUserLearningMap=new HashMap<>();
            list.forEach(courseId -> {
                futures.add(CompletableFuture.supplyAsync(() ->statisticUserCourseLearning(courseId, userId)));
            });
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            contactUserLearnings=futures.stream().map(CompletableFuture::join).toList();
            contactUserLearningMap=contactUserLearnings.stream().collect(Collectors.toMap(ContactUserLearning::getCourseId, contactUserLearning -> contactUserLearning));
            courseTotalNum = list.size();
            List<Course> courses=productRepository.findCourseByIds(list);
            for (Long courseId : list) {
                Map<Long, Course> courseMap = courses.stream().collect(Collectors.toMap(Course::getId, course -> course));
                ContactUserLearning courseLearning = contactUserLearningMap.get(courseId);
                courseLearning.setCourseName(courseMap.get(courseId).getName().getValue());
                courseLearning.setImgUrl(courseMap.get(courseId).getImageUrl());
                userLearningSecondTotal=ObjUtil.defaultIfNull(userLearningSecondTotal, 0L)+(courseLearning.getUserLearningSecondTotal()==null?0L:courseLearning.getUserLearningSecondTotal());
                payKnowledgeNodeNum=ObjUtil.defaultIfNull(payKnowledgeNodeNum, 0) + (courseLearning.getPayKnowledgeNodeNum()==null?0:courseLearning.getPayKnowledgeNodeNum());
                payKnowledgeNodePriceSum=payKnowledgeNodePriceSum.add(courseLearning.getPayKnowledgeNodePriceSum()==null?BigDecimal.ZERO:courseLearning.getPayKnowledgeNodePriceSum());
                freeUnlockKnowledgeNodePriceSum=freeUnlockKnowledgeNodePriceSum.add(courseLearning.getFreeUnlockKnowledgeNodePriceSum()==null?BigDecimal.ZERO:courseLearning.getFreeUnlockKnowledgeNodePriceSum());
                freeUnlockKnowledgeNodeNum=ObjUtil.defaultIfNull(freeUnlockKnowledgeNodeNum, 0) + (courseLearning.getFreeUnlockKnowledgeNodeNum()==null?0:courseLearning.getFreeUnlockKnowledgeNodeNum());
                courseSecondTotal=ObjUtil.defaultIfNull(courseSecondTotal, 0D)+ObjUtil.defaultIfNull(courseLearning.getClassDuration(), 0D);
                courseTimeTotal=ObjUtil.defaultIfNull(courseTimeTotal, 0L)+ (courseLearning.getUserLearningSecondTotal()==null?0:courseLearning.getUserLearningSecondTotal());
//                if (courseLearning.isInLearning()) {
//                    inLearningCourseNum++;
//                }
                if (courseLearning.getLearnProgress() >90) {
                    finishCourseNum++;
                }else{
                    inLearningCourseNum++;
                }
            }

        }
        contactUserLearnings= contactUserLearnings.stream().sorted(Comparator.comparing(ContactUserLearning::getLastLearnTimeSecond)).toList();
        if (CollUtil.isNotEmpty(contactUserLearnings)){
            courseStatisticVo.setLastLearnTime(new Date(contactUserLearnings.getLast().getLastLearnTimeSecond()));
        }else {
            courseStatisticVo.setLastLearnTime(new Date());
        }
        courseStatisticVo.setCourseSecondTotal(courseTimeTotal);
        courseStatisticVo.setCourseTotalNum(courseTotalNum);
        courseStatisticVo.setInLearningCourseNum(inLearningCourseNum);
        courseStatisticVo.setFinishCourseNum(finishCourseNum);
        courseStatisticVo.setUserLearningSecondTotal(userLearningSecondTotal);
        courseStatisticVo.setPayKnowledgeNodeNum(payKnowledgeNodeNum);
        courseStatisticVo.setPayKnowledgeNodePriceSum(payKnowledgeNodePriceSum);
        courseStatisticVo.setFreeUnlockKnowledgeNodeNum(freeUnlockKnowledgeNodeNum);
        courseStatisticVo.setFreeUnlockKnowledgeNodePriceSum(freeUnlockKnowledgeNodePriceSum);
        courseStatisticVo.setCourseLearningVoList(contactUserLearnings);

        return courseStatisticVo;
    }
    /**
     * 统计用户学习课程
     *
     * @param userId
     * @return
     */
    public ContactUserLearning statisticUserCourseLearning(Long courseId, Long userId) {
        ContactUserLearning courseLearning = new ContactUserLearning();
        courseLearning.setCourseId(courseId);
        List<CourseKnowledgeNode> courseKnowledgeNodeList = productRepository.findListByCourseId(courseId, "", true);
        Map<Long, CourseKnowledgeNode> courseKnowledgeMap = new HashMap<>();
        if (CollUtil.isNotEmpty(courseKnowledgeNodeList)) {
            courseKnowledgeMap = courseKnowledgeNodeList.stream().collect(Collectors.toMap(CourseKnowledgeNode::getId, courseKnowledgeNode -> courseKnowledgeNode));
        }
        List<ContactUserCourseKnowledge> myCourseKnowledgeList = contactUserCourseRepository.getMyCourseKnowledgeList(userId, courseId);
        Double durationTotal=0d;
        BigDecimal coursePrice=BigDecimal.ZERO;

        //统计课程时长
        if (CollUtil.isNotEmpty(courseKnowledgeNodeList)) {
            courseLearning.setKnowledgeNodeNum(courseKnowledgeNodeList.size());
            for (CourseKnowledgeNode courseKnowledge : courseKnowledgeNodeList) {
                Double t = ObjUtil.defaultIfNull(courseKnowledge.getDuration(), 0d);
                durationTotal+=t;
                BigDecimal price = ObjUtil.defaultIfNull(courseKnowledge.getPrice().getPrice(), BigDecimal.ZERO);
                coursePrice=coursePrice.add(price);

            }
        }
        courseLearning.setKnowledgeNodeNum(CollUtil.isNotEmpty(courseKnowledgeNodeList)?courseKnowledgeNodeList.size():0);
        courseLearning.setPrice(coursePrice);
        courseLearning.setClassDuration(durationTotal);
        //统计课程学习时长
        if (CollUtil.isNotEmpty(myCourseKnowledgeList)) {
            Integer freeUnlockKnowledgeNodeNum=0;
            Integer payKnowledgeNodeNum=0;
            //知识点课程时长
            BigDecimal freeUnlockKnowledgeNodePriceSum=BigDecimal.ZERO;
            BigDecimal payKnowledgeNodePriceSum=BigDecimal.ZERO;
            Long userLearningSecondTotal=0L;
            Long lastLearnTimeSecond=0L;
            for (ContactUserCourseKnowledge courseKnowledge : myCourseKnowledgeList) {
                BigDecimal price = ObjUtil.defaultIfNull(courseKnowledgeMap.get(courseKnowledge.getKnowledgeNodeId()).getPrice().getPrice(), BigDecimal.ZERO);

                if (courseKnowledge.getUnlockType() == 2) {
                    freeUnlockKnowledgeNodeNum++;
                    freeUnlockKnowledgeNodePriceSum=freeUnlockKnowledgeNodePriceSum.add(price);

                } else {
                    payKnowledgeNodeNum++;
                    payKnowledgeNodePriceSum = payKnowledgeNodePriceSum.add(price);
                }
                //学习时长
                userLearningSecondTotal += ObjUtil.defaultIfNull(courseKnowledge.getWatchLength(),0L);

                //课程的最后学习时间
                if (courseKnowledge.getLastPlayTime() != null) {
                    courseLearning.setLastLearnDateTime(courseKnowledge.getLastPlayTime());
                    //先记录最后学习时间的毫秒，也好比较，后面再转成可视时间字符串
                    Long playTime = Date.from(courseKnowledge.getLastPlayTime().atZone(ZoneId.systemDefault()).toInstant()).getTime();
                    if (lastLearnTimeSecond<playTime) {
                        lastLearnTimeSecond=playTime;
                    }
                }
            }
            courseLearning.setPayKnowledgeNodeNum(payKnowledgeNodeNum);
            courseLearning.setFreeUnlockKnowledgeNodeNum(freeUnlockKnowledgeNodeNum);
            courseLearning.setPayKnowledgeNodePriceSum(payKnowledgeNodePriceSum);
            courseLearning.setFreeUnlockKnowledgeNodePriceSum(freeUnlockKnowledgeNodePriceSum);
            courseLearning.setUserLearningSecondTotal(userLearningSecondTotal);
            courseLearning.setLastLearnTimeSecond(lastLearnTimeSecond);
             courseLearning.setLastLearnTime("");
        }else {
            courseLearning.setPayKnowledgeNodeNum(0);
            courseLearning.setFreeUnlockKnowledgeNodeNum(0);
            courseLearning.setPayKnowledgeNodePriceSum(BigDecimal.ZERO);
            courseLearning.setFreeUnlockKnowledgeNodePriceSum(BigDecimal.ZERO);
            courseLearning.setUserLearningSecondTotal(0L);
            courseLearning.setLastLearnTimeSecond(0L);
            courseLearning.setLastLearnTime("");
        }
        //
        Long lastPlayTime = ObjUtil.defaultIfNull(courseLearning.getLastLearnTimeSecond(), 0L);
        //一个月内学习
        if (lastPlayTime != null && lastPlayTime > 0L && new Date(lastPlayTime).getTime() - 30 * 24 * 60 * 60 * 1000L < new Date().getTime()) {
            courseLearning.setInLearning(true);
        } else {
            courseLearning.setInLearning(false);
        }
        Double progress=0d;
        if (courseLearning.getClassDuration()!=null&&courseLearning.getClassDuration()!=0){
            progress= ObjUtil.defaultIfNull(courseLearning.getUserLearningSecondTotal(),0d).doubleValue()*100/courseLearning.getClassDuration();
        }
        courseLearning.setLearnProgress(BigDecimal.valueOf(progress).setScale(2,  RoundingMode.HALF_UP).doubleValue());
        return courseLearning;
    }

}